package cn.com.netedge.iot.frontend.datasave.service.impl;

import cn.com.netedge.iot.common.constants.CacheKeyConstants;
import cn.com.netedge.iot.common.constants.Globals;
import cn.com.netedge.iot.common.utils.RedisUtil;
import cn.com.netedge.iot.common.utils.StringUtil;
import cn.com.netedge.iot.fe.datasave.dao.*;
import cn.com.netedge.iot.frontend.datasave.dao.*;
import cn.com.netedge.iot.frontend.datasave.model.freeze.ColumnDataModel;
import cn.com.netedge.iot.frontend.datasave.model.freeze.EventModel;
import cn.com.netedge.iot.frontend.datasave.model.freeze.FreezeDataModel;
import cn.com.netedge.iot.frontend.datasave.model.freeze.FreezeEventDataModel;
import cn.com.netedge.iot.frontend.datasave.model.online.DataCOnlineModel;
import cn.com.netedge.iot.frontend.datasave.model.prm.PrmCtptBase;
import cn.com.netedge.iot.frontend.datasave.service.DataSaveService;
import cn.com.netedge.iot.frontend.datasave.vo.DynamicColumnsRecordVO;
import cn.com.netedge.iot.frontend.datasave.vo.DynamicTableVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class DataSaveServiceImpl implements DataSaveService {

    private static final Logger logger = LoggerFactory.getLogger(DataSaveServiceImpl.class);

    @Autowired
    private DataFreezeMapper dataFreezeMapper;
    @Autowired
    private DataCOnlineMapper dataCOnlineMapper;
    @Autowired
    private DataCEvtMapper dataCEvtMapper;
    @Autowired
    private DataECommunicationMapper dataECommunicationMapper;
    @Autowired
    private DataEDisconnectorMapper dataEDisconnectorMapper;
    @Autowired
    private PrmCtptBaseMapper prmCtptBaseMapper;
    @Autowired
    private DataEFraudDetectionMapper dataEFraudDetectionMapper;
    @Autowired
    private DataEPowerfailureMapper dataEPowerfailureMapper;
    @Autowired
    private DataEPowerqualityMapper dataEPowerqualityMapper;
    @Autowired
    private DataEStandardMapper dataEStandardMapper;
    @Autowired
    private DataEVoltagequalityMapper dataEVoltagequalityMapper;
    @Autowired
    private DataCMonthlyMapper dataCMonthlyMapper;
    @Autowired
    private DataCDailyMapper dataCDailyMapper;
    @Autowired
    private DataCLoadMapper dataCLoadMapper;
    @Autowired
    private DataCLoadSecondMapper dataCLoadSecondMapper;

    @Override
    public void saveFreezeDataModel(List<FreezeDataModel> list) {
        if (list != null && list.size() > 0) {
            dataFreezeMapper.insertFreezeDataBatch(list);
        }
    }

    //日、月冻结、曲线 动态列数据处理
    private DynamicTableVO getFreezeDataDynamicTable(List<FreezeDataModel> list) {
        String columns = "meter_id,save_time,data_time";
        String tableName = list.get(0).getTableName();
        String dynamicColumns = getDynamicColumns(tableName);
        String[] columnArr = {};
        if (StringUtil.isNotEmpty(dynamicColumns)) {
            columns += "," + dynamicColumns;
            columnArr = columns.split(",");
        } else {
            columnArr = columns.split(",");
        }
        Date now = new Date();
        List<DynamicColumnsRecordVO> values = new ArrayList<>();
        for (FreezeDataModel data : list) {
            DynamicColumnsRecordVO record = new DynamicColumnsRecordVO();
            values.add(record);
            List<ColumnDataModel> modelList = data.getColumnDataModels();
            List<Object> valueList = new ArrayList<>(columnArr.length);
            record.setValueList(valueList);
            if (modelList == null || modelList.isEmpty()) {
                continue;
            }
            for (String fieldName : columnArr) {
                if (fieldName.equalsIgnoreCase("save_time")) {
                    valueList.add(now);
                } else if (fieldName.equalsIgnoreCase("meter_id")) {
                    valueList.add(data.getMeterId());
                } else {
                    valueList.add(getValue(fieldName, modelList));
                }
            }
        }
        return new DynamicTableVO(columns, values);
    }

    @Override
    public void saveFreezeMonthlyDataModel(List<FreezeDataModel> list) {
        if (list != null && list.size() > 0) {
            DynamicTableVO vo = getFreezeDataDynamicTable(list);
            dataCMonthlyMapper.batchInsert(vo.getColumn(), vo.getList());
        }
    }

    @Override
    public void saveFreezeDailyDataModel(List<FreezeDataModel> list) {
        if (list != null && list.size() > 0) {
            DynamicTableVO vo = getFreezeDataDynamicTable(list);
            dataCDailyMapper.batchInsert(vo.getColumn(), vo.getList());
        }
    }

    @Override
    public void saveFreezeLoadDataModel(List<FreezeDataModel> list) {
        if (list != null && list.size() > 0) {
            DynamicTableVO vo = getFreezeDataDynamicTable(list);
            dataCLoadMapper.batchInsert(vo.getColumn(), vo.getList());
        }
    }

    @Override
    public void saveFreezeLoadSecondDataModel(List<FreezeDataModel> list) {
        if (list != null && list.size() > 0) {
            DynamicTableVO vo = getFreezeDataDynamicTable(list);
            dataCLoadSecondMapper.batchInsert(vo.getColumn(), vo.getList());
        }
    }

    @Override
    public void saveFreezeEventDataModel(List<FreezeEventDataModel> list) {
        if (list != null && list.size() > 0) {
            dataFreezeMapper.insertFreezeEventDataModel(list);
        }
    }

    private String getDynamicColumns(String tableName) {
        String key = CacheKeyConstants.KEY_TABLE_COLUMNS + tableName;
        String result = RedisUtil.get(key);
        if (StringUtil.isNotEmpty(result)) {
            return result;
        }
        PrmCtptBase base = prmCtptBaseMapper.selectByTableName(tableName);
        if (base == null) {
            return null;
        }
        result = base.getCtpt();
        if (StringUtil.isEmpty(result)) {
            return null;
        }
        RedisUtil.set(key, result, Globals.DEFAULT_CACHE_EXPIRE_TIME, TimeUnit.SECONDS);
        return result;
    }

    private DynamicTableVO getDynamicTable(List<FreezeEventDataModel> list) {
        String columns = "protocol,meter_id,save_time,event_id,data_time";
        String tableName = list.get(0).getTableName();
        String dynamicColumns = getDynamicColumns(tableName);
        String[] columnArr = {};
        if (StringUtil.isNotEmpty(dynamicColumns)) {
            columns += "," + dynamicColumns;
            columnArr = columns.split(",");
        } else {
            columnArr = columns.split(",");
        }
        Date now = new Date();
        List<DynamicColumnsRecordVO> values = new ArrayList<>();
        for (FreezeEventDataModel data : list) {
            DynamicColumnsRecordVO record = new DynamicColumnsRecordVO();
            values.add(record);
            List<ColumnDataModel> modelList = data.getColumnDataModels();
            List<Object> valueList = new ArrayList<>(columnArr.length);
            record.setValueList(valueList);
            if (modelList == null || modelList.isEmpty()) {
                continue;
            }
            for (String fieldName : columnArr) {
                if (fieldName.equalsIgnoreCase("save_time")) {
                    valueList.add(now);
                } else if (fieldName.equalsIgnoreCase("protocol")) {
                    valueList.add(data.getProtocol());
                } else if (fieldName.equalsIgnoreCase("meter_id")) {
                    valueList.add(data.getDeviceId());
                } else {
                    valueList.add(getValue(fieldName, modelList));
                }
            }
        }
        return new DynamicTableVO(columns, values);
    }

    @Override
    public void saveFreezeEventCommunicationDataModel(List<FreezeEventDataModel> list) {
        if (list != null && list.size() > 0) {
            DynamicTableVO vo = getDynamicTable(list);
            dataECommunicationMapper.batchInsert(vo.getColumn(), vo.getList());
        }
    }

    private Object getValue(String fieldName, List<ColumnDataModel> modelList) {
        for (ColumnDataModel model : modelList) {
            if (model.getColumnName().equalsIgnoreCase(fieldName)) {
                return model.getDataValue();
            }
        }
        return null;
    }

    @Override
    public void saveFreezeEventDisconnectorDataModel(List<FreezeEventDataModel> list) {
        if (list != null && list.size() > 0) {
            DynamicTableVO vo = getDynamicTable(list);
            dataEDisconnectorMapper.batchInsert(vo.getColumn(), vo.getList());
        }
    }

    @Override
    public void saveFreezeEventFrauddetectionDataModel(List<FreezeEventDataModel> list) {
        if (list != null && list.size() > 0) {
            DynamicTableVO vo = getDynamicTable(list);
            dataEFraudDetectionMapper.batchInsert(vo.getColumn(), vo.getList());
        }
    }

    @Override
    public void saveFreezeEventPowerfailureDataModel(List<FreezeEventDataModel> list) {
        if (list != null && list.size() > 0) {
            DynamicTableVO vo = getDynamicTable(list);
            dataEPowerfailureMapper.batchInsert(vo.getColumn(), vo.getList());
        }
    }

    @Override
    public void saveFreezeEventPowerqualityDataModel(List<FreezeEventDataModel> list) {
        if (list != null && list.size() > 0) {
            DynamicTableVO vo = getDynamicTable(list);
            dataEPowerqualityMapper.batchInsert(vo.getColumn(), vo.getList());
        }
    }

    @Override
    public void saveFreezeEventStandardDataModel(List<FreezeEventDataModel> list) {
        if (list != null && list.size() > 0) {
            DynamicTableVO vo = getDynamicTable(list);
            dataEStandardMapper.batchInsert(vo.getColumn(), vo.getList());
        }
    }

    @Override
    public void saveFreezeEventVoltagequalityDataModel(List<FreezeEventDataModel> list) {
        if (list != null && list.size() > 0) {
            DynamicTableVO vo = getDynamicTable(list);
            dataEVoltagequalityMapper.batchInsert(vo.getColumn(), vo.getList());
        }
    }


    @Override
    public void saveDataCOnlineModel(List<DataCOnlineModel> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        dataCOnlineMapper.insertOnlineDataBatch(list);
    }

    @Override
    public void saveEventDataModel(List<EventModel> list) {
        if (list != null && list.size() > 0) {
            dataCEvtMapper.insertEventDataBatch(list);
        }

    }
}
